#include <Rectangle.h>
#include <Precision.h>
#include <cmath>
#include <Geometry.h>

#include <Condition.h>
#include <IsGtThan.h>
#include <IsLsThan.h>
#include <IsNotGtThan.h>
#include <IsNotLsThan.h>
#include <Precision.h>


namespace
{
    Precision PRECISION_FLOOR(2, std::floor),
                PRECISION_ROUND(2, round);

    IsGtThan IS_GREATER_THAN(0);

    IsNotGtThan IS_NOT_GREATER_THAN(100);

    IsLsThan IS_LESS_THAN(75);

    Checker LENGTH_CHECKER(&IS_GREATER_THAN, &IS_NOT_GREATER_THAN),
            WIDTH_CHECKER(&IS_GREATER_THAN, &IS_LESS_THAN);

}
Rectangle::Rectangle(double length, double width) :
    length_m(length, &PRECISION_FLOOR, &LENGTH_CHECKER),
    width_m(width,&PRECISION_FLOOR, &WIDTH_CHECKER)
{
    updateValidState();
}

double
Rectangle::getArea() const
{
    double area = rectangleState_m->getArea(length_m, width_m);

    return Precision(2, round)(area);
}

double
Rectangle::getPerimeter() const
{
    return rectangleState_m->getPerimeter(length_m, width_m);
}

bool
Rectangle::isValid() const
{
    return rectangleState_m->isValid();
}

bool
Rectangle::changeLength(double length)
{
    bool isDone = length_m.change(length);
    updateValidState();
    return isDone;
}

bool
Rectangle::changeWidth(double width)
{
    bool isDone = width_m.change(width);
    updateValidState();
    return isDone;
}

void
Rectangle::updateValidState()
{
    rectangleState_m = getGeometry(length_m, width_m);
}

